#ifndef VERTEX_HULL_HPP
#define VERTEX_HULL_HPP

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <assert.h> 

#include <SFML/System/Vector2.hpp>

#include <SmegTools/Config.h>

#include "../QuadTree/QuadTreeOccupant.hpp"

#include <SmegTools/Debug/DebugNew.hpp>

namespace smeg {
    namespace light {
        class ShadowCasterEntity;
        
////////////////////////////////////////////////////////////
/// Represents a hull
////////////////////////////////////////////////////////////
class Hull : public QuadTreeOccupant
{
public:
    ////////////////////////////////////////////////////////////
    /// Default Constructor
    ///
    /// \param _Center :        Center of the hull
    /// \param _fAngleDeg :     Rotation angle
    /// \param _bIsStatic :     Static or dynamic ?
    /// \param _pParent :       Shadow caster parent if any
    ///
    ////////////////////////////////////////////////////////////
                                Hull( const sf::Vector2f& _Center       = sf::Vector2f(), 
                                        float _fAngleDeg                = 0.0f,
                                        bool _bIsStatic                 = false,
                                        ShadowCasterEntity* _pParent    = NULL );
    ////////////////////////////////////////////////////////////
    /// Copy Constructor
    ///
    /// \param _Copy :          Hull to copy from
    ///
    ////////////////////////////////////////////////////////////
                                Hull( const Hull& _Copy );
    ////////////////////////////////////////////////////////////
    /// Destructor
    ///
    ////////////////////////////////////////////////////////////
    virtual                     ~Hull();
    
    ////////////////////////////////////////////////////////////
    /// Render the hull
    ///
    /// \param _Color :         Color to render the hull
    ///
    ////////////////////////////////////////////////////////////
    void                        Render( const sf::Color& _Color = sf::Color::White ) const;
    
    ////////////////////////////////////////////////////////////
    /// Is the given point inside the hull
    ///
    /// \param _Point :         Point to test
    ///
    /// \return Whether the point is inside the hull or not
    ///
    ////////////////////////////////////////////////////////////
    virtual bool                IsPointInHull( const sf::Vector2f& _Point ) const = 0;
    
    /*********************** Accessors ************************/
    virtual void                SetAngleRad( float _fAngleRad );
    virtual void                RotateRad( float _fAngleRad );
    
    const sf::Vector2f&         GetLocalVertex( const unsigned _uIndex ) const;
    sf::Vector2f                GetWorldVertex( const unsigned _uIndex ) const;
    unsigned                    GetNumVertices() const;

    void                        SetParent( ShadowCasterEntity* _pParent );

protected:
    friend class LightSystem;
    
    ////////////////////////////////////////////////////////////
    /// Render the vertices
    ///
    ////////////////////////////////////////////////////////////
    virtual void                RenderVertices() const;
    
    ////////////////////////////////////////////////////////////
    /// Compute the hull
    ///
    ////////////////////////////////////////////////////////////
    void                        ComputeHull();
    
    ////////////////////////////////////////////////////////////
    /// Center the hull
    ///
    ////////////////////////////////////////////////////////////
    void                        CenterHull();
    ////////////////////////////////////////////////////////////
    /// Rotate the vertices
    ///
    ////////////////////////////////////////////////////////////
    void                        RotateVertices();
    ////////////////////////////////////////////////////////////
    /// Compute the AABB
    ///
    ////////////////////////////////////////////////////////////
    virtual void                ComputeAABB();
    
    ////////////////////////////////////////////////////////////
    /// Clear the hull of all of its vertices
    ///
    ////////////////////////////////////////////////////////////
    void                        Clear();

    /******************* Protected members ********************/
    unsigned                    m_uNumVertices;                 /// Number of vertices representing the hull
    sf::Vector2f*               m_pOriginalVertices;            /// Original vertices
    sf::Vector2f*               m_pVertices;                    /// Vertices transformed by rotation

    light::ShadowCasterEntity*  m_pParent;                      /// Shadow caster entity possessing this hull

#ifdef _DEBUG
public:
    virtual void                DebugRender( const sf::Color& _Color = sf::Color::White ) const;
#endif // _DEBUG
};

/************************** Inline ************************/
inline const sf::Vector2f& Hull::GetLocalVertex( const unsigned _uIndex ) const {
    assert( _uIndex >=0 && _uIndex < m_uNumVertices );
    return m_pVertices[_uIndex];
}

inline sf::Vector2f Hull::GetWorldVertex( const unsigned _uIndex ) const {
    assert( _uIndex >=0 && _uIndex < m_uNumVertices );
    return m_pVertices[_uIndex] + m_Center;
}

inline unsigned Hull::GetNumVertices() const {
    return m_uNumVertices;
}

inline void Hull::SetParent( ShadowCasterEntity* _pParent ) {
    m_pParent = _pParent;
}

    } // smeg::light
} // smeg

#include <SmegTools/Debug/DebugNewOff.hpp>

#endif // VERTEX_HULL_HPP
